package com.zhijian.wharf.service;

import cn.hutool.core.codec.Base64;
import com.google.code.kaptcha.Producer;
import com.zhijian.BusinessException;
import com.zhijian.autoconfigure.cache.CacheClient;
import com.zhijian.response.enums.ResponseCodeEnum;
import com.zhijian.util.EncryptUtil;
import com.zhijian.wharf.config.Constants;
import com.zhijian.wharf.entity.po.User;
import com.zhijian.wharf.entity.vo.response.AuthVo;
import com.zhijian.wharf.entity.vo.response.CaptchaVo;
import com.zhijian.wharf.util.IdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.FastByteArrayOutputStream;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author HCG
 * @version 1.0
 * @date 2023-05-05
 */
public abstract class LoginAbstract {

    @Autowired
    private UserService userService;

    @Autowired
    @Qualifier("captchaProducerMath")
    private Producer captchaProducerMath;

    @Autowired
    private CacheClient cacheClient;

    /**
     * 登录
     *
     * @param vo
     * @return
     */
    public abstract AuthVo login(Serializable vo);

    /**
     * 用户登出
     *
     * @param token 登录token
     * @return
     */
    public abstract boolean logout(String token);

    /**
     * 修改密码
     *
     * @param id
     * @param oldPassword
     * @param newPassword
     * @return
     */
    public boolean changePassword(Long id, String oldPassword, String newPassword) {
        User person = userService.selectById(id);
        if (Objects.isNull(person)) {
            throw new BusinessException(ResponseCodeEnum.FAILURE.code, "用户不存在或者已被删除");
        }
        //校验：账号密码正确性校验
        String pwdMd5 = EncryptUtil.password(oldPassword, person.getSalt());
        if (!pwdMd5.equals(person.getPassword())) {
            throw new BusinessException(ResponseCodeEnum.FAILURE.code, "旧密码不正确");
        }
        userService.updateByPrimaryKeySelective(User.builder()
                .id(id)
                .password(EncryptUtil.password(newPassword, person.getSalt()))
                .updateTime(new Date())
                .build());
        return true;
    }

    /**
     * 生成验证码
     *
     * @return
     */
    public CaptchaVo generateCaptcha() {
        // 保存验证码信息
        String uuid = IdUtils.simpleUUID();
        String verifyKey = Constants.Redis.CAPTCHA_CODE_KEY + uuid;

        String capStr, code = null;
        BufferedImage image = null;

        // 生成验证码
        String captchaType = "math";
        if ("math".equals(captchaType)) {
            String capText = captchaProducerMath.createText();
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            code = capText.substring(capText.lastIndexOf("@") + 1);
            image = captchaProducerMath.createImage(capStr);
        }
//        } else if ("char".equals(captchaType)) {
//            capStr = code = captchaProducer.createText();
//            image = captchaProducer.createImage(capStr);
//        }

        cacheClient.set(verifyKey, code, 2, TimeUnit.MINUTES);
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try {
            ImageIO.write(image, "jpg", os);
        } catch (IOException e) {
            e.printStackTrace();
        }
        CaptchaVo captchaVo = new CaptchaVo();
        captchaVo.setUuid(uuid);
        captchaVo.setImg(Base64.encode(os.toByteArray()));
        return captchaVo;
    }
}
